package netty.simple.netty;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.util.CharsetUtil;

;import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.concurrent.TimeUnit;

/**
 * @ClassName ServerHandler
 * @Description TODO
 * @Author director吴
 * @Date 2022/1/19 12:56
 * @Version 1.0
 *
 *  ****   自定义handler需要继承netty指定的 handler 适配器，此时我们定义handler 才能被纳入到netty的 handler 工作组中
 *
 **/
public class ServerHandler extends ChannelInboundHandlerAdapter {



    /**   读取数据  -- -- 读取客户端发送的消息
     *
     *    ChannelHandlerContext  :上下文对象-----可以获取【通道】 【管道】 【地址】  。。。等很多信息
     *                  Object   :客户端发送的数据
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {

        System.out.println("ChannelHandlerContext:---"+ctx);

        //将msg 转换未btyeBtuffer
        ByteBuf byteBuffer = (ByteBuf) msg;    //ByteBuf  == netty 提供的
        System.out.println("客户端发送的消息是："+byteBuffer.toString(CharsetUtil.UTF_8));
        System.out.println("客户端地址是："+ctx.channel().remoteAddress());

        //异步模型解决方案

        //自定义普通任务
        ctx.channel().eventLoop().execute(new Runnable() {
            @Override
            public void run() {
                System.out.println("自定义普通任务！");
                System.out.println("上下文调用线程组 execute（）方法");
            }
        });


        //自定义定时任务
        ctx.channel().eventLoop().schedule(new Runnable() {
            @Override
            public void run() {
                System.out.println("自定义定时任务！");
                System.out.println("上下文调用线程组 schedule（）方法");
                System.out.println("传参（线程任务，时间值number，时间单位TimeUnit.SECONDS/DAY之类）");
            }
        }, 5, TimeUnit.SECONDS);

    }


    /**   数据读取完毕---  回复消息
     */
    @Override
    public void channelReadComplete(ChannelHandlerContext ctx) throws Exception {

        /*
        ChannelHandlerContext  的写入方法  有
                  ctx.writeAndFlush()   ----写入到 【缓存区域】并  【刷新】--刷新就是将缓存的属性再写入到管道
                  ctx.write()           ----写入   【缓存区域】，并没有将数据刷新到管道
         */


        //需要对发送的数据进修编码
        ctx.writeAndFlush(Unpooled.copiedBuffer("hello,客户端", CharsetUtil.UTF_8));
    }




    /**   异常处理
     */
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        ctx.close();
    }
}
